home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * Mesa 3-D graphics library
- * Version: 2.3
- * Copyright (C) 1995-1997 Brian Paul
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
- /*
- * amigamesartl.c
- *
- * Version 1.0 27 Jun 1998
- * by Jarno van der Linden
- * jarno@kcbbs.gen.nz
- *
- * Based on ddsample.c ver 1.5
- *
- * Version 1.1 02 Aug 1998
- * by Jarno van der Linden
- * jarno@kcbbs.gen.nz
- *
- * - Fixed several bugs in glClear()
- * - QUICKLOOP macros added
- * - Noticed that { *x = p; x++; } is faster than { *x++ = p; }
- * - Quantizer changed to plugin library
- * - Use environment variables to select quantizer
- *
- */
-
-
- /*
- * This is a sample template for writing new Mesa device drivers.
- * You'll have to rewrite all the pseudo code below.
- *
- * Let's say you're interfacing Mesa to a window/operating system
- * called FOO. Replace all occurances of FOOMesa with the real name
- * you select for your interface (i.e. XMesa, WMesa, AmigaMesa).
- *
- * You'll have to design an API for clients to use, defined in a
- * header called Mesa/include/GL/FooMesa.h Use the sample as an
- * example. The API should at least have functions for creating
- * rendering contexts, binding rendering contexts to windows/frame
- * buffers, etc.
- *
- * Next, you'll have to write implementations for the device driver
- * functions described in dd.h
- *
- * Note that you'll usually have to flip Y coordinates since Mesa's
- * window coordinates start at the bottom and increase upward. Most
- * window system's Y-axis increases downward
- *
- * Functions marked OPTIONAL may be completely omitted by your driver.
- *
- * Your Makefile should compile this module along with the rest of
- * the core Mesa library.
- */
-
-
- #include <stdlib.h>
- #include "GL/amigamesartl.h"
- #include "context.h"
- #include "depth.h"
- #include "macros.h"
- #include "matrix.h"
- #include "types.h"
- #include "vb.h"
-
- #include "gl/quantizer.h"
-
- #include <intuition/intuition.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/utility.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- #include <m68881.h>
-
- #define RGBA(r,g,b,a) (((r)<<24) | ((g)<<16) | ((b)<<8) | (a))
-
- #define WINWIDTH(w) ((w)->Width - (w)->BorderLeft - (w)->BorderRight)
- #define WINHEIGHT(w) ((w)->Height - (w)->BorderTop - (w)->BorderBottom)
-
-
- #define QUICKLOOP16(n,l) { register int ql_var; \
- for(ql_var=0; ql_var<((n) & 15); ql_var++) \
- { l; }\
- for(; ql_var<(n); ql_var+=16) \
- { l; l; l; l; l; l; l; l; l; l; l; l; l; l; l; l; } \
- }
-
- #define QUICKLOOP8(n,l) { register int ql_var; \
- for(ql_var=0; ql_var<((n) & 7); ql_var++) \
- { l; }\
- for(; ql_var<(n); ql_var+=8) \
- { l; l; l; l; l; l; l; l; } \
- }
-
- #define QUICKLOOP4(n,l) { register int ql_var; \
- for(ql_var=0; ql_var<((n) & 3); ql_var++) \
- { l; }\
- for(; ql_var<(n); ql_var+=4) \
- { l; l; l; l; } \
- }
-
- #define QUICKLOOP2(n,l) { register int ql_var; \
- for(ql_var=0; ql_var<((n) & 1); ql_var++) \
- { l; }\
- for(; ql_var<(n); ql_var+=2) \
- { l; l; } \
- }
-
- #define QUICKLOOP1(n,l) { register int ql_var; \
- for(ql_var=0; ql_var<(n); ql_var++) \
- { l; } \
- }
-
-
- /*
- * This struct contains all device-driver state information. Think of it
- * as an extension of the core GLcontext from types.h.
- */
- struct amiga_mesa_rtl_context {
- GLcontext *gl_ctx; /* the core library context */
- GLvisual *gl_visual;
- GLframebuffer *gl_buffer; /* The depth, stencil, accum, etc buffers */
- GLboolean rgb_flag; /* RGB mode? */
- struct Window *the_window; /* Window pointer */
- struct DrawInfo *di; /* DrawInfo pointer for screen info */
- unsigned long *buffer; /* The image buffer */
- GLint width, height; /* Size of image buffer */
- GLint wwidth, wheight; /* Window width and height */
- unsigned long pixel; /* current color index or RGBA pixel value */
- unsigned long clearpixel; /* pixel for clearing the color buffers */
- unsigned long numcolours; /* Number of colours to use for this context */
- unsigned long colourbase; /* First colour table index */
- struct Library *quantizer; /* Quantizer library */
- char qname[48]; /* Name of quantizer */
- ULONG qver; /* Version of quantizer */
- /* etc... */
- };
-
-
- static AmigaMesaRTLContext Current = NULL;
- static struct Library *quantizerBase = NULL;
-
- static const char *renderer_string(void)
- {
- return "AmigaMesaRTL";
- }
-
-
- static void clear_index( GLcontext *ctx, GLuint index )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- /* implement glClearIndex */
- /* usually just save the color index value in the amesartl struct */
- amesartl->clearpixel = amesartl->colourbase + index;
- }
-
-
- static void clear_color( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- /* implement glClearColor */
- /* color components are floats in [0,1] */
- /* usually just save the value in the amesartl struct */
- amesartl->clearpixel = RGBA(r,g,b,a);
- }
-
-
- static void clear( GLcontext *ctx,
- GLboolean all, GLint x, GLint y, GLint width, GLint height )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- unsigned long *bp;
- unsigned char *bbp;
- unsigned long p;
- /*
- * Clear the specified region of the current color buffer using the clear
- * color or index as specified by one of the two functions above.
- * If all==GL_TRUE, clear whole buffer, else just clear region defined
- * by x,y,width,height
- */
-
- p = amesartl->clearpixel;
- y = amesartl->wheight-1-y;
-
- if(amesartl->rgb_flag)
- {
- if(all)
- {
- bp = amesartl->buffer;
- QUICKLOOP16(amesartl->width*amesartl->height,
- {
- *bp = p;
- bp++;
- }
- )
- }
- else
- {
- bp = amesartl->buffer+y*amesartl->width+x;
- QUICKLOOP16(height,
- {
- QUICKLOOP16(width,
- {
- *bp = p;
- bp++;
- }
- )
- bp -= amesartl->width + width;
- }
- )
- }
- }
- else
- {
- if(all)
- {
- memset(amesartl->buffer, p, amesartl->width * amesartl->height);
- }
- else
- {
- bbp = ((unsigned char *)amesartl->buffer)+y*amesartl->width+x;
- QUICKLOOP16(height,
- {
- memset(bbp, p, width);
- bbp -= amesartl->width;
- }
- )
- }
- }
- }
-
-
- static void set_index( GLcontext *ctx, GLuint index )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- /* Set the current color index. */
- amesartl->pixel = amesartl->colourbase + index;
- }
-
-
- static void set_color( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- /* Set the current RGBA color. */
- /* r is in [0,ctx->Visual->RedScale] */
- /* g is in [0,ctx->Visual->GreenScale] */
- /* b is in [0,ctx->Visual->BlueScale] */
- /* a is in [0,ctx->Visual->AlphaScale] */
- amesartl->pixel = RGBA(r,g,b,a);
- }
-
-
- static GLboolean set_buffer( GLcontext *ctx, GLenum mode )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- /* set the current drawing/reading buffer, return GL_TRUE or GL_FALSE */
- /* for success/failure */
- if (mode==GL_FRONT)
- {
- return GL_TRUE;
- }
- else
- {
- return GL_FALSE;
- }
- }
-
-
- static void get_buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- /* return the width and height of the current buffer */
- /* if anything special has to been done when the buffer/window is */
- /* resized, do it now */
- GLuint rw,rh;
-
- *width = amesartl->wwidth = WINWIDTH(amesartl->the_window);
- *height = amesartl->wheight = WINHEIGHT(amesartl->the_window);
-
- rw = (((amesartl->wwidth + 15)>>4)<<4);
- rh = amesartl->wheight;
-
- if((rw != amesartl->width) || (rh != amesartl->height))
- {
- if(amesartl->buffer) free(amesartl->buffer);
- amesartl->buffer = NULL;
-
- amesartl->width = rw;
- amesartl->height = rh;
-
- amesartl->buffer = calloc(amesartl->width * amesartl->height, amesartl->rgb_flag ? sizeof(unsigned long) : sizeof(unsigned char));
-
- quantizerBase = amesartl->quantizer;
- ResizeQuantizer(amesartl->width,amesartl->height);
- }
- }
-
-
- static void write_color_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- const GLubyte red[], const GLubyte green[],
- const GLubyte blue[], const GLubyte alpha[],
- const GLubyte mask[] )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- unsigned long *bp;
- const GLubyte *ri,*gi,*bi,*ai,*mi;
-
- y = amesartl->wheight-1-y;
- bp = amesartl->buffer+y*amesartl->width+x;
- ri = red;
- gi = green;
- bi = blue;
- ai = alpha;
- mi = mask;
-
- if (mask)
- {
- QUICKLOOP1(n,
- {
- if (*mi)
- *bp = RGBA(*ri,*gi,*bi,*ai);
- mi++;
- bp++;
- ri++;
- gi++;
- bi++;
- ai++;
- }
- )
- }
- else
- {
- QUICKLOOP1(n,
- {
- *bp = RGBA(*ri,*gi,*bi,*ai);
- bp++;
- ri++;
- gi++;
- bi++;
- ai++;
- }
- )
- }
- }
-
-
- static void write_monocolor_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- const GLubyte mask[])
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- unsigned long *bp;
- const GLubyte *mi;
- unsigned long p;
-
- y = amesartl->wheight-1-y;
- bp = amesartl->buffer+y*amesartl->width+x;
- mi = mask;
- p = amesartl->pixel;
-
- QUICKLOOP1(n,
- {
- if (*mi)
- *bp = p;
- mi++;
- bp++;
- }
- )
- }
-
-
- static void write_color_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLubyte r[], const GLubyte g[],
- const GLubyte b[], const GLubyte a[],
- const GLubyte mask[] )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- const GLubyte *ri,*gi,*bi,*ai,*mi;
- const GLint *xi,*yi;
-
- ri = r;
- gi = g;
- bi = b;
- ai = a;
- mi = mask;
- xi = x;
- yi = y;
-
- QUICKLOOP1(n,
- {
- if (*mi)
- *(amesartl->buffer + (amesartl->wheight-1-*yi) * amesartl->width + *xi) = RGBA(*ri,*gi,*bi,*ai);
- mi++;
- ri++;
- gi++;
- bi++;
- ai++;
- xi++;
- yi++;
- }
- )
- }
-
-
- static void write_monocolor_pixels( GLcontext *ctx,
- GLuint n,
- const GLint x[], const GLint y[],
- const GLubyte mask[] )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- const GLubyte *mi;
- const GLint *xi,*yi;
- unsigned long p;
-
- mi = mask;
- xi = x;
- yi = y;
- p = amesartl->pixel;
-
- QUICKLOOP1(n,
- {
- if (*mi)
- *(amesartl->buffer + (amesartl->wheight-1-*yi) * amesartl->width + *xi) = p;
- mi++;
- xi++;
- yi++;
- }
- )
- }
-
-
- static void write_index_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- const GLuint index[],
- const GLubyte mask[] )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- unsigned char *bbp;
- const GLuint *ii;
- const GLubyte *mi;
- const unsigned long base = amesartl->colourbase;
-
- y = amesartl->wheight-1-y;
- bbp = ((unsigned char *)amesartl->buffer)+y*amesartl->width+x;
- ii = index;
- mi = mask;
-
- QUICKLOOP1(n,
- {
- if (*mi)
- *bbp = *ii + base;
- mi++;
- bbp++;
- ii++;
- }
- )
- }
-
-
- static void write_monoindex_span( GLcontext *ctx,
- GLuint n,GLint x,GLint y,const GLubyte mask[] )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- unsigned char *bbp;
- unsigned long p;
- const GLubyte *mi;
-
- y = amesartl->wheight-1-y;
- bbp = ((unsigned char *)amesartl->buffer)+y*amesartl->width+x;
- mi = mask;
- p = amesartl->pixel;
-
- QUICKLOOP1(n,
- {
- if (*mi)
- *bbp = p;
- mi++;
- bbp++;
- }
- )
- }
-
-
- static void write_index_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLuint index[], const GLubyte mask[] )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- const GLuint *ii;
- const GLubyte *mi;
- const GLint *xi,*yi;
- const unsigned long base = amesartl->colourbase;
-
- ii = index;
- mi = mask;
- xi = x;
- yi = y;
-
- QUICKLOOP1(n,
- {
- if (*mi)
- *(((unsigned char *)amesartl->buffer) + (amesartl->wheight-1-*yi) * amesartl->width + *xi) = *ii + base;
- mi++;
- ii++;
- xi++;
- yi++;
- }
- )
- }
-
-
- static void write_monoindex_pixels( GLcontext *ctx,
- GLuint n,
- const GLint x[], const GLint y[],
- const GLubyte mask[] )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- unsigned long p;
- const GLubyte *mi;
- const GLint *xi,*yi;
-
- p = amesartl->pixel;
- mi = mask;
- xi = x;
- yi = y;
-
- QUICKLOOP1(n,
- {
- if (*mi)
- *(((unsigned char *)amesartl->buffer) + (amesartl->wheight-1-*yi) * amesartl->width + *xi) = p;
- mi++;
- xi++;
- yi++;
- }
- )
- }
-
-
- static void read_index_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, GLuint index[])
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- const unsigned char *bbp;
- GLuint *ii;
- const unsigned long base = amesartl->colourbase;
-
- y = amesartl->wheight-1-y;
- bbp = ((unsigned char *)amesartl->buffer)+y*amesartl->width+x;
- ii = index;
-
- QUICKLOOP1(n,
- {
- *ii = *bbp - base;
- ii++;
- bbp++;
- }
- )
- }
-
-
- static void read_color_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- GLubyte red[], GLubyte green[],
- GLubyte blue[], GLubyte alpha[] )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- const unsigned char *bbp;
- GLubyte *ri,*gi,*bi,*ai;
-
- y = amesartl->wheight-1-y;
- bbp = (unsigned char *)(amesartl->buffer+y*amesartl->width+x);
- ri = red;
- gi = green;
- bi = blue;
- ai = alpha;
-
- QUICKLOOP1(n,
- {
- *ri = *bbp;
- ri++;
- bbp++;
- *gi = *bbp;
- gi++;
- bbp++;
- *bi = *bbp;
- bi++;
- bbp++;
- *ai = *bbp;
- ai++;
- bbp++;
- }
- )
- }
-
-
- static void read_index_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLuint indx[], const GLubyte mask[] )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- const GLint *xi,*yi;
- GLuint *ii;
- const GLubyte *mi;
- const unsigned long base = amesartl->colourbase;
-
- ii = indx;
- xi = x;
- yi = y;
- mi = mask;
- QUICKLOOP1(n,
- {
- if(*mi)
- *ii = *(((unsigned char *)amesartl->buffer) + (amesartl->wheight-1-*yi) * amesartl->width + *xi) - base;
- mi++;
- xi++;
- yi++;
- ii++;
- }
- )
- }
-
-
- static void read_color_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLubyte red[], GLubyte green[],
- GLubyte blue[], GLubyte alpha[],
- const GLubyte mask[] )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- const unsigned char *bbp;
- GLubyte *ri,*gi,*bi,*ai;
- const GLint *xi,*yi;
- const GLubyte *mi;
-
- ri = red;
- gi = green;
- bi = blue;
- ai = alpha;
- xi = x;
- yi = y;
- mi = mask;
-
- QUICKLOOP1(n,
- {
- if(*mi)
- {
- bbp = (unsigned char *)(amesartl->buffer + (amesartl->wheight-1-*yi) *amesartl->width + *xi);
- *ri = *bbp;
- bbp++;
- *gi = *bbp;
- bbp++;
- *bi = *bbp;
- bbp++;
- *ai = *bbp;
- bbp++;
- }
- mi++;
- ri++;
- gi++;
- bi++;
- ai++;
- xi++;
- yi++;
- }
- )
- }
-
-
-
- static void finish( GLcontext *ctx )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- /* OPTIONAL FUNCTION: implements glFinish if possible */
- }
-
-
-
- static void flush( GLcontext *ctx )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- /* OPTIONAL FUNCTION: implements glFlush if possible */
-
- /* OK. The big one. Dump the buffer to the window */
-
- /* See if the window is the size we expect it to be. */
- /* If not, better not do anything, we might write into non-existent */
- /* window space. We expect a redraw soon anyway. */
- if((WINWIDTH(amesartl->the_window) != amesartl->wwidth) ||
- (WINHEIGHT(amesartl->the_window) != amesartl->wheight))
- return;
-
- quantizerBase = amesartl->quantizer;
- Quantize(amesartl->buffer);
- }
-
-
- static GLboolean index_mask( GLcontext *ctx, GLuint mask )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- /* OPTIONAL FUNCTION: implement glIndexMask if possible, else
- * return GL_FALSE
- */
- return(GL_FALSE);
- }
-
-
- static GLboolean color_mask( GLcontext *ctx,
- GLboolean rmask, GLboolean gmask,
- GLboolean bmask, GLboolean amask)
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- /* OPTIONAL FUNCTION: implement glColorMask if possible, else
- * return GL_FALSE
- */
- return(GL_FALSE);
- }
-
-
- static GLboolean logicop( GLcontext *ctx, GLenum op )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- /*
- * OPTIONAL FUNCTION:
- * Implements glLogicOp if possible. Return GL_TRUE if the device driver
- * can perform the operation, otherwise return GL_FALSE. If GL_FALSE
- * is returned, the logic op will be done in software by Mesa.
- */
- return(GL_FALSE);
- }
-
-
- static void dither( GLcontext *ctx, GLboolean enable )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- /* OPTIONAL FUNCTION: enable/disable dithering if applicable */
- }
-
-
- static void error( GLcontext *ctx )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- /* OPTIONAL FUNCTION: catch error */
- }
-
-
- /**********************************************************************/
- /***** Optimized triangle rendering *****/
- /**********************************************************************/
- /* (Based on osmesa.c) */
-
- /*
- * Smooth-shaded, z triangle, RGBA color.
- */
- static void smooth_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
- GLuint v2, GLuint pv )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- #define INTERP_Z 1
- #define INTERP_RGB 1
- #define INTERP_ALPHA 1
- #define INNER_LOOP( LEFT, RIGHT, Y ) \
- { \
- const GLint len = RIGHT-LEFT; \
- unsigned long *bp; \
- GLdepth *zr = zRow; \
- GLdepth z; \
- bp = amesartl->buffer+(amesartl->wheight-1-Y)*amesartl->width+LEFT; \
- QUICKLOOP1(len, \
- { \
- z = FixedToDepth(ffz); \
- if (z < *zr) { \
- *zr = z; \
- *bp = RGBA(FixedToInt(ffr), FixedToInt(ffg), \
- FixedToInt(ffb), FixedToInt(ffa) ); \
- } \
- ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; ffa += fdadx; \
- ffz += fdzdx; \
- bp++; \
- zr++; \
- } \
- ) \
- }
- #include "tritemp.h"
- }
-
-
- /*
- * Flat-shaded, z triangle, RGBA color.
- */
- static void flat_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
- GLuint v2, GLuint pv )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- #define INTERP_Z 1
- #define SETUP_CODE \
- GLubyte r = VB->Color[pv][0]; \
- GLubyte g = VB->Color[pv][1]; \
- GLubyte b = VB->Color[pv][2]; \
- GLubyte a = VB->Color[pv][3]; \
- unsigned long p = RGBA(r,g,b,a);
-
- #define INNER_LOOP( LEFT, RIGHT, Y ) \
- { \
- const GLint len = RIGHT-LEFT; \
- unsigned long *bp; \
- GLdepth *zr = zRow; \
- GLdepth z; \
- bp = amesartl->buffer+(amesartl->wheight-1-Y)*amesartl->width+LEFT; \
- QUICKLOOP1(len, \
- { \
- z = FixedToDepth(ffz); \
- if (z < *zr) { \
- *zr = z; \
- *bp = p; \
- } \
- ffz += fdzdx; \
- bp++; \
- zr++; \
- } \
- ) \
- }
- #include "tritemp.h"
- }
-
-
-
- /*
- * Smooth-shaded, z-less triangle, RGBA color.
- */
- static void smooth_color_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
- GLuint v2, GLuint pv )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- #define INTERP_RGB 1
- #define INTERP_ALPHA 1
- #define INNER_LOOP( LEFT, RIGHT, Y ) \
- { \
- const GLint len = RIGHT-LEFT; \
- unsigned long *bp; \
- bp = amesartl->buffer+(amesartl->wheight-1-Y)*amesartl->width+LEFT; \
- QUICKLOOP1(len, \
- { \
- *bp = RGBA(FixedToInt(ffr), FixedToInt(ffg), \
- FixedToInt(ffb), FixedToInt(ffa) ); \
- ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; ffa += fdadx; \
- bp++; \
- } \
- ) \
- }
- #include "tritemp.h"
- }
-
-
- /*
- * Flat-shaded, z triangle, RGBA color.
- */
- static void flat_color_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
- GLuint v2, GLuint pv )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
- #define SETUP_CODE \
- GLubyte r = VB->Color[pv][0]; \
- GLubyte g = VB->Color[pv][1]; \
- GLubyte b = VB->Color[pv][2]; \
- GLubyte a = VB->Color[pv][3]; \
- unsigned long p = RGBA(r,g,b,a);
-
- #define INNER_LOOP( LEFT, RIGHT, Y ) \
- { \
- const GLint len = RIGHT-LEFT; \
- unsigned long *bp; \
- bp = amesartl->buffer+(amesartl->wheight-1-Y)*amesartl->width+LEFT; \
- QUICKLOOP1(len, \
- { \
- *bp = p; \
- bp++; \
- } \
- ) \
- }
- #include "tritemp.h"
- }
-
-
- /*
- * Return pointer to an accelerated triangle function if possible.
- */
- static triangle_func choose_triangle_function( GLcontext *ctx )
- {
- struct amiga_mesa_rtl_context *amesartl = (struct amiga_mesa_rtl_context *) ctx->DriverCtx;
-
- if(amesartl->rgb_flag == GL_FALSE)
- return NULL;
-
- if (ctx->Polygon.SmoothFlag) return NULL;
- if (ctx->Polygon.StippleFlag) return NULL;
- if (ctx->Texture.Enabled) return NULL;
-
- if (ctx->RasterMask==DEPTH_BIT
- && ctx->Depth.Func==GL_LESS
- && ctx->Depth.Mask==GL_TRUE)
- {
- if (ctx->Light.ShadeModel==GL_SMOOTH) {
- return smooth_color_z_triangle;
- }
- else
- {
- return flat_color_z_triangle;
- }
- }
- else if(ctx->RasterMask==0)
- {
- if (ctx->Light.ShadeModel==GL_SMOOTH) {
- return smooth_color_triangle;
- }
- else
- {
- return flat_color_triangle;
- }
- }
-
- return NULL;
- }
-
-
-
- /**********************************************************************/
- /**********************************************************************/
-
-
- static void setup_DD_pointers( GLcontext *ctx )
- {
- /* Initialize all the pointers in the DD struct. Do this whenever */
- /* a new context is made current or we change buffers via set_buffer! */
-
- ctx->Driver.RendererString = renderer_string;
- ctx->Driver.UpdateState = setup_DD_pointers;
-
- ctx->Driver.ClearIndex = clear_index;
- ctx->Driver.ClearColor = clear_color;
- ctx->Driver.Clear = clear;
-
- ctx->Driver.Index = set_index;
- ctx->Driver.Color = set_color;
-
- ctx->Driver.SetBuffer = set_buffer;
- ctx->Driver.GetBufferSize = get_buffer_size;
-
- /* Pixel/span writing functions: */
- ctx->Driver.WriteColorSpan = write_color_span;
- ctx->Driver.WriteMonocolorSpan = write_monocolor_span;
- ctx->Driver.WriteColorPixels = write_color_pixels;
- ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;
- ctx->Driver.WriteIndexSpan = write_index_span;
- ctx->Driver.WriteMonoindexSpan = write_monoindex_span;
- ctx->Driver.WriteIndexPixels = write_index_pixels;
- ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;
-
- /* Pixel/span reading functions: */
- ctx->Driver.ReadIndexSpan = read_index_span;
- ctx->Driver.ReadColorSpan = read_color_span;
- ctx->Driver.ReadIndexPixels = read_index_pixels;
- ctx->Driver.ReadColorPixels = read_color_pixels;
-
- ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
-
- /*
- * OPTIONAL FUNCTIONS: these may be left uninitialized if the device
- * driver can't/needn't implement them.
- */
- ctx->Driver.Flush = flush;
- #if 0
- ctx->Driver.Finish = finish;
- ctx->Driver.IndexMask = index_mask;
- ctx->Driver.ColorMask = color_mask;
- ctx->Driver.LogicOp = logicop;
- ctx->Driver.Dither = dither;
- ctx->Driver.Error = error;
- ctx->Driver.NearFar = near_far;
- #endif
- }
-
-
-
- /**********************************************************************/
- /***** FOO/Mesa API Functions *****/
- /**********************************************************************/
-
-
- __asm __saveds AmigaMesaRTLContext AmigaMesaRTLCreateContextA( register __a0 struct Window *window, register __a1 struct TagItem *tags )
- {
- AmigaMesaRTLContext c;
- GLboolean rgb_flag, alpha_flag, db_flag;
- GLint depth_bits, stencil_bits, accum_bits, index_bits;
- GLfloat red_scale, green_scale, blue_scale, alpha_scale;
- GLint red_bits, green_bits, blue_bits, alpha_bits;
- int maxnumcolours;
- char *strp,str[32];
-
- c = (AmigaMesaRTLContext) calloc( 1, sizeof(struct amiga_mesa_rtl_context) );
- if (!c)
- {
- AmigaMesaRTLDestroyContext( c );
- return NULL;
- }
-
- rgb_flag = GetTagData(AMRTL_RGBAMode, (ULONG)TRUE, tags) ? GL_TRUE : GL_FALSE;
- rgb_flag = GetTagData(AMRTL_IndexMode, (ULONG)FALSE, tags) ? GL_FALSE : rgb_flag;
-
- if(rgb_flag)
- {
- /* RGB(A) mode */
- alpha_flag = GL_FALSE;
- db_flag = GL_FALSE;
- depth_bits = DEPTH_BITS;
- stencil_bits = STENCIL_BITS;
- accum_bits = ACCUM_BITS;
- index_bits = 0;
- red_scale = 255.0;
- green_scale = 255.0;
- blue_scale = 255.0;
- alpha_scale = 255.0;
- red_bits = 8;
- green_bits = 8;
- blue_bits = 8;
- alpha_bits = 0;
- }
- else
- {
- /* color index mode */
- alpha_flag = GL_FALSE;
- db_flag = GL_FALSE;
- depth_bits = DEPTH_BITS;
- stencil_bits = STENCIL_BITS;
- accum_bits = ACCUM_BITS;
- index_bits = 8;
- red_scale = 0.0;
- green_scale = 0.0;
- blue_scale = 0.0;
- alpha_scale = 0.0;
- red_bits = 8;
- green_bits = 8;
- blue_bits = 8;
- alpha_bits = 0;
- }
-
- /* Create core visual */
- c->gl_visual = gl_create_visual( rgb_flag,
- alpha_flag,
- db_flag,
- depth_bits,
- stencil_bits,
- accum_bits,
- index_bits,
- red_scale, green_scale, blue_scale, alpha_scale,
- red_bits, green_bits, blue_bits, alpha_bits );
-
- if(!c->gl_visual)
- {
- AmigaMesaRTLDestroyContext( c );
- return NULL;
- }
-
- c->gl_ctx = gl_create_context( c->gl_visual,
- NULL,
- (void *) c );
-
- if(!c->gl_ctx)
- {
- AmigaMesaRTLDestroyContext( c );
- return NULL;
- }
-
- c->gl_buffer = gl_create_framebuffer( c->gl_visual );
- if(!c->gl_buffer)
- {
- AmigaMesaRTLDestroyContext( c );
- return NULL;
- }
-
- c->rgb_flag = rgb_flag;
- c->the_window = window;
- c->di = GetScreenDrawInfo(c->the_window->WScreen);
- if(!c->di)
- {
- AmigaMesaRTLDestroyContext( c );
- return NULL;
- }
- c->buffer = NULL;
- c->width = 0;
- c->height = 0;
- c->wwidth = WINWIDTH(c->the_window);
- c->wheight = WINHEIGHT(c->the_window);
- c->pixel = 0;
- c->clearpixel = 0;
- maxnumcolours = 1L<<c->di->dri_Depth;
- c->numcolours = GetTagData(AMRTL_NumColours, maxnumcolours, tags);
- c->colourbase = GetTagData(AMRTL_ColourBase, (ULONG)0, tags);
- if(c->colourbase > (maxnumcolours-2))
- c->colourbase = maxnumcolours-2;
- if(c->colourbase < 0)
- c->colourbase = 0;
- if((c->colourbase + c->numcolours) > maxnumcolours)
- {
- c->numcolours = maxnumcolours-c->colourbase;
- }
- if(c->numcolours < 2)
- c->numcolours = 2;
-
- strcpy(c->qname,"quantizers/");
- if(GetVar("AmigaMesaRTL/Quantizer",str,32,0) == -1)
- strcpy(str,"dl1");
- strp = (char *)GetTagData(AMRTL_Quantizer, NULL, tags);
- if(strp)
- {
- strncpy(str,strp,32);
- str[31] = '\0';
- }
- strcat(c->qname,str);
-
- c->qver = 0;
- if(GetVar("AmigaMesaRTL/QuantizerVersion",str,32,0) != -1)
- c->qver = atol(str);
- c->qver = GetTagData(AMRTL_QuantizerVersion, c->qver, tags);
-
- c->quantizer = OpenLibrary(c->qname,c->qver);
- if(!c->quantizer)
- {
- AmigaMesaRTLDestroyContext( c );
- return NULL;
- }
-
- quantizerBase = c->quantizer;
- if(!InitQuantizer(window, rgb_flag ? AMRTL_RGBAMode : AMRTL_IndexMode, c->numcolours, c->colourbase))
- {
- AmigaMesaRTLDestroyContext( c );
- return NULL;
- }
-
- return c;
- }
-
-
-
- __asm __saveds void AmigaMesaRTLDestroyContext( register __a0 AmigaMesaRTLContext c )
- {
- if(c)
- {
- if(c->quantizer)
- {
- quantizerBase = c->quantizer;
- DeleteQuantizer();
- CloseLibrary(c->quantizer);
- }
-
- if(c->di) FreeScreenDrawInfo(c->the_window->WScreen, c->di);
- c->di = NULL;
-
- if(c->gl_buffer) gl_destroy_framebuffer( c->gl_buffer );
- c->gl_buffer = NULL;
-
- if(c->gl_ctx) gl_destroy_context( c->gl_ctx );
- c->gl_ctx = NULL;
-
- if(c->gl_visual) gl_destroy_visual( c->gl_visual );
- c->gl_visual = NULL;
-
- if(c->buffer) free(c->buffer);
- c->buffer = NULL;
-
- free(c);
- }
- c = NULL;
- }
-
-
-
- /*
- * Make the specified context the current one
- * Might also want to specify the window/drawable here, like for GLX.
- */
- __asm __saveds void AmigaMesaRTLMakeCurrent( register __a0 AmigaMesaRTLContext c )
- {
- gl_make_current( c->gl_ctx, c->gl_buffer );
- setup_DD_pointers( c->gl_ctx );
- gl_Viewport( c->gl_ctx, 0, 0, c->wwidth, c->wheight );
-
- Current = c;
- }
-
-
- __asm __saveds AmigaMesaRTLContext AmigaMesaRTLGetCurrentContext( void )
- {
- return Current;
- }
-
-
- /* you may need to add other FOO/Mesa functions too... */
-
-